#include "Particle.h"

ParticleSystem::ParticleSystem(void){
	endPosX = 0.0;
	endPosZ = 0.0;
	startPosY = 0.0;

	srand(time(NULL));
}

ParticleSystem::~ParticleSystem(void){
}

void ParticleSystem::InitParticle(int MaxNumberOfParticles, float startPosY, float endPosX, float endPosZ, bool Particle3D){
	MaxParticle = MaxNumberOfParticles;
	ps = new Particle[MaxParticle];

	this->Particle3D = Particle3D;
	this->endPosX = endPosX;
	this->endPosZ = endPosZ;

	this->startPosY = startPosY;

	for (int i = 0; i < MaxParticle; i++){
		float x = (((float) rand() / RAND_MAX) - 0.5f) / 15;
		float y = (((float) rand() / RAND_MAX) / 2);
		float z = 0;
		if(Particle3D)
			z = (((float) rand() / RAND_MAX) - 0.5f) / 15;
		ps[i].vel = Vector3D(x,y,z); // Direction

		float random = ((float)rand()/(float)RAND_MAX);
		x = ((random * endPosX)) - (endPosX / 2);
		y = ((float) rand()/RAND_MAX);
		random = ((float)rand()/(float)RAND_MAX);
		z = ((random * endPosZ)) - (endPosZ / 2);

		ps[i].pos = Vector3D(x,y,z); // Position
		
		float r = ((float) rand()/RAND_MAX);
		float g = ((float) rand()/RAND_MAX);
		float b = ((float) rand()/RAND_MAX);
		float a = ((float) rand()/RAND_MAX);

		random = ((float)rand()/(float)RAND_MAX);
		ps[i].angle = (random * 360.0) + 1.0;
		
		ps[i].r = r; 
		ps[i].g = g; 
		ps[i].b = b; //Color
		ps[i].life = a;
	}

	particleDL = glGenLists(1);
	glNewList(particleDL, GL_COMPILE);
	if(Particle3D){
		glPushMatrix();
		glBegin(GL_QUADS);
			//+z
			glVertex3f ( 0, 0, CUBE_SIZE);
			glVertex3f ( CUBE_SIZE, 0, CUBE_SIZE);
			glVertex3f ( CUBE_SIZE, CUBE_SIZE, CUBE_SIZE);
			glVertex3f ( 0, CUBE_SIZE, CUBE_SIZE);
			//+x
			glVertex3f ( CUBE_SIZE, 0, CUBE_SIZE);
			glVertex3f ( CUBE_SIZE, 0, 0);
			glVertex3f ( CUBE_SIZE, CUBE_SIZE, 0);
			glVertex3f ( CUBE_SIZE, CUBE_SIZE, CUBE_SIZE);
			//-z
			glVertex3f ( CUBE_SIZE, 0, 0);
			glVertex3f ( 0, 0, 0);
			glVertex3f ( 0, CUBE_SIZE, 0);
			glVertex3f ( CUBE_SIZE, CUBE_SIZE, 0);
			//-x
			glVertex3f ( 0, 0, 0);
			glVertex3f ( 0, 0, CUBE_SIZE);
			glVertex3f ( 0, CUBE_SIZE, CUBE_SIZE);
			glVertex3f ( 0, CUBE_SIZE, 0);
			//+y
			glVertex3f ( 0, CUBE_SIZE, CUBE_SIZE);
			glVertex3f ( CUBE_SIZE, CUBE_SIZE, CUBE_SIZE);
			glVertex3f ( CUBE_SIZE, CUBE_SIZE, 0);
			glVertex3f ( 0, CUBE_SIZE, 0);
			//-y
			glVertex3f ( 0, 0, 0);
			glVertex3f ( CUBE_SIZE, 0, 0);
			glVertex3f ( CUBE_SIZE, 0, CUBE_SIZE);
			glVertex3f ( 0, 0, CUBE_SIZE);
		glEnd();
		glPopMatrix();
	}else{
		glPushMatrix();
			glBegin(GL_QUADS);
				//Back
				glVertex2f(0, 0);
				glVertex2f(0, 5);
				glVertex2f(5, 5);
				glVertex2f(5, 0);
				
				//Front
				glVertex2f(0, 0);
				glVertex2f(5, 0);
				glVertex2f(5, 5);
				glVertex2f(0, 5);
			glEnd();
		glPopMatrix();
	}
	glEndList();
}

void ParticleSystem::RenderParticle(void){
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	glPushMatrix();
	glTranslatef(50, 0, 0);
	for(int i = 0; i < MaxParticle; i++){
		glPushMatrix();
		glTranslatef( ps[i].pos.x, ps[i].pos.y + startPosY, ps[i].pos.z);
		if(Particle3D)
			glRotatef(ps[i].angle, ps[i].r, ps[i].g, ps[i].b);
			glColor4f(ps[i].r, ps[i].g, ps[i].b, ps[i].life);
			glCallList(particleDL);
		glPopMatrix();
	}
	glPopMatrix();
	
	//glDisableClientState(GL_VERTEX_ARRAY);  // disable vertex arrays
 //   glDisableClientState(GL_COLOR_ARRAY);
 //   glDisableClientState(GL_NORMAL_ARRAY);

 //   // it is good idea to release VBOs with ID 0 after use.
 //   // Once bound with 0, all pointers in gl*Pointer() behave as real
 //   // pointer, so, normal vertex array operations are re-activated
 //   glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
	glDisable(GL_BLEND);
}

void ParticleSystem::UpdateParticle(float elapsedTime, float lifeDecrease, float particleSpeed){
	for (int i = 0; i < MaxParticle; i++){
		ps[i].pos = ps[i].pos - ps[i].vel * particleSpeed * elapsedTime;
		ps[i].life -= lifeDecrease * elapsedTime;

		if(ps[i].life <= 0){
			float x = (((float) rand() / RAND_MAX) - 0.5f) / 15;
			float y = ((float) rand() / RAND_MAX) / 2;
			float z = 0;
			if(Particle3D)
				z = (((float) rand() / RAND_MAX) - 0.5f) / 15;
			
			ps[i].vel = Vector3D(x, y, z);

			float random = ((float)rand()/(float)RAND_MAX);
			x = ((random * endPosX)) - (endPosX / 2);
			y = ((float) rand()/RAND_MAX);
			random = ((float)rand()/(float)RAND_MAX);
			z = ((random * endPosZ)) - (endPosZ / 2);
			ps[i].pos = Vector3D(x, y, z);

			random = ((float)rand()/(float)RAND_MAX);
			ps[i].angle = (random * 360.0) + 1.0;
				
			float a = ((float) rand() / RAND_MAX);
			ps[i].life = a;
		}
	}
}